package com.game.game.service.account;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.game.common.Transmitter;
import com.game.common.constants.GlobalConstants;
import com.game.core.net.common.RemoteNode;
import com.game.core.service.PublicService;
import com.game.core.service.ServiceContainer;
import com.game.dbpersistence.game.entity.AccountEntity;
import com.game.dbpersistence.game.entity.BuncherEntity;
import com.game.dbpersistence.game.entity.FashionEntity;
import com.game.dbpersistence.game.entity.ItemEntity;
import com.game.dbpersistence.game.entity.MakingEntity;
import com.game.dbpersistence.game.entity.MissionEntity;
import com.game.dbpersistence.game.entity.WeaponEntity;
import com.game.dbpersistence.game.entity.WeaponsetEntity;
import com.game.game.GameServer;
import com.game.game.config.AttributeConfig;
import com.game.game.config.XMLTemplateService;
import com.game.game.service.room.RoomService;
import com.game.game.service.server.ServerService;
import com.game.game.service.team.TeamService;
import com.game.message.proto.account.AccountProtoBuf.BGAccountModifyREQ;
import com.game.message.proto.account.AccountProtoBuf.GWAccountLoginRES;
import com.game.message.proto.account.AccountProtoBuf.GWAccountLogoutRES;
import com.game.message.proto.account.AccountProtoBuf.GWAccountModifySYN;
import com.game.message.proto.account.AccountProtoBuf.GWSynMoneyInfoRES;
import com.game.message.proto.account.AccountProtoBuf.WGAccountLoginREQ;
import com.game.message.proto.battle.BattleProtoBuf.WGPlayerOfflineSYN;
import com.game.message.proto.player.PlayerProtoBuf.AttributeInfo;
import com.game.message.protocol.ProtocolsConfig;

public class AccountLoginService extends PublicService {
	final static Logger logger = LoggerFactory.getLogger(AccountLoginService.class);
	private static final long serialVersionUID = -95924175253120279L;
	private ArrayList<String> allowLoginInPlatForm = new ArrayList<String>(); // game允许登录的平台名称集合
	public Lock lock = new ReentrantLock();

	public void reloadFormDB() {
		lock.lock();
		allowLoginInPlatForm.clear();
		lock.unlock();
	}

	public GWAccountLoginRES accountLogin(RemoteNode remoteNode, WGAccountLoginREQ message, int callback) {
		GWAccountLoginRES.Builder sendBuilder = GWAccountLoginRES.newBuilder();
		String accountName = message.getAccount();
		//String platform = message.getPlatform();
		String accountID = message.getAccountID();
		//int channelId = message.getClientChannel();
		//String deviceId = message.hasDeviceId() ? message.getDeviceId() : "";
		sendBuilder.setResult(1);
		sendBuilder.setPoints(0);
		sendBuilder.setAccount(accountName);
		sendBuilder.setAccountID(accountID);
		
		try {
			if (GameServer.classPathXmlApplicationContext == null) {
				GameServer.classPathXmlApplicationContext = new ClassPathXmlApplicationContext(
						new String[] { "bean/applicationContext.xml" });
			}
			if (GameServer.accountEntityService == null) {
				GameServer.accountEntityService = GameServer.getAccountEntityProxyService(GameServer.classPathXmlApplicationContext);
			}
			if (GameServer.buncherEntityService == null) {
				GameServer.buncherEntityService = GameServer.getBuncherEntityProxyService(GameServer.classPathXmlApplicationContext);
			}
			if (GameServer.fashionEntityService == null) {
				GameServer.fashionEntityService = GameServer.getFashionEntityProxyService(GameServer.classPathXmlApplicationContext);
			}
			if (GameServer.itemEntityService == null) {
				GameServer.itemEntityService = GameServer.getItemEntityProxyService(GameServer.classPathXmlApplicationContext);
			}
			if (GameServer.makingEntityService == null) {
				GameServer.makingEntityService = GameServer.getMakingEntityProxyService(GameServer.classPathXmlApplicationContext);
			}
			if (GameServer.missionEntityService == null) {
				GameServer.missionEntityService = GameServer.getMissionEntityProxyService(GameServer.classPathXmlApplicationContext);
			}
			if (GameServer.teamEntityService == null) {
				GameServer.teamEntityService = GameServer.getTeamEntityProxyService(GameServer.classPathXmlApplicationContext);
			}
			if (GameServer.weaponEntityService == null) {
				GameServer.weaponEntityService = GameServer.getWeaponEntityProxyService(GameServer.classPathXmlApplicationContext);
			}
			if (GameServer.weaponsetEntityService == null) {
				GameServer.weaponsetEntityService = GameServer.getWeaponsetEntityProxyService(GameServer.classPathXmlApplicationContext);
			}

			AccountEntity account = GameServer.accountEntityService.getAccount(accountName);
			if (account == null) {
				account = new AccountEntity();
				account.setAcc(accountName);
				account.setSex(0);
				account.setWeaponSet(1);
				account.setLevel(1);
				long ret = GameServer.accountEntityService.insertAccount(account);
				if (ret > 0) {
					// 初始化用户数据
					// this.registPlayer(account);
					sendBuilder.setSex(account.getSex());
					sendBuilder.setAppearance(account.getAppearance());
					// 暂时解决方法，性别为0 说明该用户暂时未创建角色
					sendBuilder.setIsNew(1);
					sendBuilder.setName(account.getName());
					sendBuilder.setMissionId(account.getMissionId());
					sendBuilder.setTeamId(account.getTeamId());
					sendBuilder.setCurrentWeaponSet(account.getWeaponSet());
				} else {
					logger.error("GameServer.accountEntityService.insertAccount() Filed ! account={}",
							account.toString());
				}
			} else {
				// TODO 临时方法 删除房间
				if (account.getMissionId() != 0 && account.getTeamId() != 0) {
					TeamService teamService = ServiceContainer.getInstance().getPublicService(TeamService.class);
					teamService.tmpDestoryRoom(account.getTeamId(), account.getMissionId());
				}
				
				sendBuilder.setSex(account.getSex());
				sendBuilder.setAppearance(account.getAppearance());
				// 暂时解决方法，性别为0 说明该用户暂时未创建角色
				if(account.getSex()==0) {
					sendBuilder.setIsNew(1);
				}else {
					sendBuilder.setIsNew(0);
				}
				sendBuilder.setName(account.getName());
				sendBuilder.setMissionId(account.getMissionId());
				sendBuilder.setTeamId(account.getTeamId());
				sendBuilder.setExperience(account.getExperience());
				sendBuilder.setGoldCoin(account.getGoldCoin());
				sendBuilder.setDiamonds(account.getDiamonds());
				sendBuilder.setGiftCert(account.getGiftCert());
				sendBuilder.setFeats(account.getFeats());
				sendBuilder.setCurrentWeaponSet(account.getWeaponSet());
				
				List<BuncherEntity> buncherList = GameServer.buncherEntityService.getBuncherList(accountName);
				if ((buncherList != null) && (buncherList.size() > 0)) {
					for (BuncherEntity entity : buncherList) {
						sendBuilder.addBuncherInfos(entity.toProto());
					}
				}
				List<FashionEntity> fashionList = GameServer.fashionEntityService.getFashionList(accountName);
				if ((fashionList != null) && (fashionList.size() > 0)) {
					for (FashionEntity entity : fashionList) {
						sendBuilder.addFashionInfos(entity.toProto());
					}
				}
				List<ItemEntity> itemList = GameServer.itemEntityService.getItemList(accountName);
				if ((itemList != null) && (itemList.size() > 0)) {
					for (ItemEntity entity : itemList) {
						sendBuilder.addItemInfos(entity.toProto());
					}
				}
				List<MakingEntity> makingList = GameServer.makingEntityService.getMakingList(accountName);
				if ((makingList != null) && (makingList.size() > 0)) {
					for (MakingEntity entity : makingList) {
						sendBuilder.addMakingInfos(entity.toProto());
					}
				}
				List<MissionEntity> missionList = GameServer.missionEntityService.getMissionList(accountName);
				if ((missionList != null) && (missionList.size() > 0)) {
					for (MissionEntity entity : missionList) {
						sendBuilder.addMissionInfos(entity.toProto());
					}
				}
				List<WeaponEntity> weaponList = GameServer.weaponEntityService.getWeaponList(accountName);
				if ((weaponList != null) && (weaponList.size() > 0)) {
					for (WeaponEntity entity : weaponList) {
						sendBuilder.addWeaponInfos(entity.toProto());
					}
				}
				List<WeaponsetEntity> weaponsetList = GameServer.weaponsetEntityService.getWeaponsetList(accountName);
				if ((weaponsetList != null) && (weaponsetList.size() > 0)) {
					for (WeaponsetEntity entity : weaponsetList) {
						sendBuilder.addWeaponSetInfos(entity.toProto());
					}
				}
			}
			// init player's attribute
			sendBuilder.setAttributeInfo(this.initAttr(accountID, account.getLevel()));
		} catch (Exception e) {
			// e.printStackTrace();
			logger.error(e.toString());
		}

		ServerService server = ServiceContainer.getInstance().getPublicService(ServerService.class);
		RemoteNode node = server.getAccountNode(accountID);
		// node存在且玩家在线才踢下线。
		if (node != null && server.isOnline(accountID)) {
			GWAccountLogoutRES.Builder res = GWAccountLogoutRES.newBuilder();
			res.setResult(ProtocolsConfig.GW_LOGOUT_KICKOFF);
			res.setAccountID(accountID);
			res.setSessionID(server.getAccountSession(accountID));
			Transmitter.getInstance().write(node, GlobalConstants.DEFAULT_CALLBACK, res.build());
		}
		server.setAccountGateway(accountID, remoteNode.getServerID(), message.getSessionID());
		server.addOnlineAccountID(accountID);

		RoomService service = ServiceContainer.getInstance().getPublicService(RoomService.class);
		Integer room = service.getRoom(accountID);
		if (room == null) {
			room = 0;
		}
		sendBuilder.setRoom(room);
		return sendBuilder.build();
	}

	public void modifyAccountInfo(RemoteNode remoteNode, BGAccountModifyREQ message, int callback) {
		GWAccountModifySYN.Builder resBuilder = GWAccountModifySYN.newBuilder();

		resBuilder.setAccountID(message.getAccountID());
		resBuilder.setId(message.getId());
		ServerService server = ServiceContainer.getInstance().getPublicService(ServerService.class);
		Transmitter.getInstance().write(server.getAccountNode(message.getAccountID()), GlobalConstants.DEFAULT_CALLBACK,
				resBuilder.build());
	}

	public void forbidAccount(String account, String platform, Long forbidTime) {
		String accountID = account + "_" + platform;
		ServerService server = ServiceContainer.getInstance().getPublicService(ServerService.class);
		RemoteNode node = server.getAccountNode(accountID);
		if (node != null && System.currentTimeMillis() < forbidTime) {
			GWAccountLogoutRES.Builder res = GWAccountLogoutRES.newBuilder();
			res.setResult(ProtocolsConfig.GW_LOGOUT_FORBID);
			res.setAccountID(accountID);
			res.setSessionID(server.getAccountSession(accountID));
			Transmitter.getInstance().write(node, GlobalConstants.DEFAULT_CALLBACK, res.build());
		}
	}

	public void removeOnlineAccountID(WGPlayerOfflineSYN message) {
		// 客户端断掉，需要判断是否处于在线状态。之前不用判断是因为remove并不会报错，而现在需要写Logout时间，则需要确定在线的才Logout
		ServerService serverService = ServiceContainer.getInstance().getPublicService(ServerService.class);
		if (serverService.isOnline(message.getAccountID())) {
			serverService.removeOnlineAccountID(message.getAccountID());

			int last = message.getAccountID().lastIndexOf(GlobalConstants.ACCOUNTID_SPLIT);
			//String account = message.getAccountID().substring(0, last);

			if (last == message.getAccountID().length()) {
				logger.error("Record logout error: platform contains {}", GlobalConstants.ACCOUNTID_SPLIT);
				return;
			}
		}
	}
    
    public AttributeInfo initAttr(String account, int level) {
		AttributeConfig attributeConfig = XMLTemplateService.attributeConfigMap.get(level);
		AttributeInfo.Builder attributeInfo = AttributeInfo.newBuilder();
		attributeInfo.setAccountID(account);
		attributeInfo.setHp(attributeConfig.getHp());
		attributeInfo.setAtt(attributeConfig.getAtt());
		attributeInfo.setDef(attributeConfig.getDef());
		attributeInfo.setCrit(attributeConfig.getCrit());
		attributeInfo.setTen(attributeConfig.getTen());
		attributeInfo.setCritDam(attributeConfig.getCritDam());
		attributeInfo.setCap(attributeConfig.getCap());
		attributeInfo.setMoveCap(attributeConfig.getMoveCap());
		attributeInfo.setSpeed(attributeConfig.getSpeed());
		attributeInfo.setOrg(attributeConfig.getOrg());
		attributeInfo.setMac(attributeConfig.getMac());
		attributeInfo.setAll(attributeConfig.getAll());
		attributeInfo.setFib(attributeConfig.getFib());
		attributeInfo.setPun(attributeConfig.getPun());
		attributeInfo.setSma(attributeConfig.getSma());
		attributeInfo.setImp(attributeConfig.getImp());
		attributeInfo.setInc(attributeConfig.getInc());
		return attributeInfo.build();
	}
    
	public void pushSynAccountInfo(String account, AccountEntity accountEntity, int source) {
		GWSynMoneyInfoRES.Builder sendBuilder = GWSynMoneyInfoRES.newBuilder();
		sendBuilder.setAccount(account);
		sendBuilder.setSynSource(source);
		sendBuilder.setExperience(accountEntity.getExperience());
		sendBuilder.setGoldCoin(accountEntity.getGoldCoin());
		sendBuilder.setDiamonds(accountEntity.getDiamonds());
		sendBuilder.setGiftCert(accountEntity.getGiftCert());
		sendBuilder.setFeats(accountEntity.getFeats());
		
		ServerService service = ServiceContainer.getInstance().getPublicService(ServerService.class);
		RemoteNode remoteNode = service.getGatewayNode(3000);
		Transmitter.getInstance().write(remoteNode, GlobalConstants.DEFAULT_CALLBACK, sendBuilder.build());
	}
	
}